package org.xlp.mvc.definition;

import org.xlp.bean.base.AbstractBeanDefinition;
import org.xlp.bean.base.IBeanCreator;
import org.xlp.bean.base.IBeanFields;
import org.xlp.bean.base.IBeanWrapper;
import org.xlp.bean.creator.NoParameterConstructorReflectBeanCreator;
import org.xlp.db.tableoption.annotation.XLPTransaction;
import org.xlp.mvc.annotation.Service;
import org.xlp.mvc.bean.ServiceAnnotationBeanCreator;
import org.xlp.mvc.util.ClassUtils;

/**
 * 注解{@link org.xlp.mvc.annotation.Service}标记类的bean定义
 *
 * Create by xlp on 2023/9/14
 */
public class ServiceAnnotationBeanDefinition extends AbstractBeanDefinition {
    /**
     * Service 注解
     */
    private Service service;

    /**
     * bean创建器，用来创建该bean定义相应的bean实例
     */
    private IBeanCreator beanCreator;

    /**
     * org.xlp.db.tableoption.annotation.XLPTransaction类名称
     * @see org.xlp.db.tableoption.annotation.XLPTransaction
     */
    private static final String XLP_TRANSACTION_CLASS_NAME = "org.xlp.db.tableoption.annotation.XLPTransaction";

    /**
     * 是否加载了org.xlp.db.tableoption.annotation.XLPTransaction类
     */
    private final boolean hasXLPTransactionClass = ClassUtils.hasClass(XLP_TRANSACTION_CLASS_NAME);

    public ServiceAnnotationBeanDefinition(IBeanFields beanFields) {
        super(beanFields);
        Class<?> beanClass = beanFields.getBeanClass();
        setServiceAnnotation(beanClass);
    }

    public ServiceAnnotationBeanDefinition(Class<?> beanClass) {
        super(beanClass);
        setServiceAnnotation(beanClass);
    }

    public ServiceAnnotationBeanDefinition(String beanClassName) {
        super(beanClassName);
        setServiceAnnotation(beanClass);
    }

    @Override
    public boolean isProxy() {
        Class<?> beanClass = getBeanClass();
        boolean proxy = service.proxy() ||
                IBeanWrapper.class.isAssignableFrom(beanClass);
        if (!proxy && hasXLPTransactionClass){
            proxy = beanClass.getAnnotation(XLPTransaction.class) != null;
        }
        return proxy;
    }

    @Override
    public boolean isSingleton() {
        return service.singleton();
    }

    @Override
    public boolean isLazy() {
        return service.lazy();
    }

    @Override
    public String getBeanId() {
        return service.id();
    }

    @Override
    public String getDescription() {
        return service.description();
    }

    /**
     * 获取bean创建器
     *
     * @return
     * @throws org.xlp.bean.exception.BeanBaseException 假如获取bean创建器失败，则抛出该异常
     */
    @Override
    public IBeanCreator getBeanCreator() {
        if (beanCreator == null) {
            if (isProxy()){
                return new ServiceAnnotationBeanCreator(getBeanClass());
            } else {
                return new NoParameterConstructorReflectBeanCreator(getBeanClass());
            }
        }
        return beanCreator;
    }

    /**
     * 设置bean创建器
     *
     * @param beanCreator
     */
    @Override
    public void setBeanCreator(IBeanCreator beanCreator) {
        this.beanCreator = beanCreator;
    }

    /**
     * 设置Controller注解
     * @param beanClass bean 类型
     * @throws IllegalArgumentException 假如给定的类没有{@link Service}注解标记，则抛出该异常
     */
    private void setServiceAnnotation(Class<?> beanClass) {
        this.service = beanClass.getDeclaredAnnotation(Service.class);
        if (service == null){
            throw new IllegalArgumentException("给的的类[" + beanClass.getName() + "]没有[" + Service.class.getName() + "]注解标记");
        }
    }
}
